use std::{
    collections::{BTreeSet, HashMap},
    fs::File,
    io::{self, BufRead},
};

#[derive(Debug)]
struct CityData(Vec<Vec<String>>);

pub fn count_provinces() -> String {
    let file = File::open("district.json").unwrap();
    let reader = io::BufReader::new(file);
    // 逐行读取 Json，因为题目给的不是正确的JSON格式
    let mut datas: HashMap<String, CityData> = HashMap::new();
    let mut key = String::new();
    let mut in_data = false;
    let mut city_data: Vec<Vec<String>> = vec![];
    for line in reader.lines() {
        let line = line.unwrap();
        let line_data = line.split('\"').collect::<Vec<&str>>();
        if line_data.len() <= 1 {
            if in_data == true {
                datas.insert(key, CityData(city_data));
                in_data = false;
                key = String::new();
                city_data = vec![];
            }
            continue;
        } // 跳过空行
        if line_data.len() == 3 {
            if in_data == true {
                // dbg!(&key);
                datas.insert(key, CityData(city_data));
                in_data = false;
                key = String::new();
                city_data = vec![];
            }
            key = line_data[1].to_string();
            in_data = true;
        } else {
            let line_data = line_data.iter().skip(1).step_by(2).map(|v| v.to_string()).collect();
            city_data.push(line_data);
        }
    }
    let mut res = vec![];
    for i in 1..=datas.len() {
        let cur_data = datas.get(&i.to_string()).unwrap();
        let mut sets: Vec<BTreeSet<String>> = vec![];
        // dbg!(&cur_data);
        for line in cur_data.0.iter() {
            let vv = line.clone();
            let mut merge = vec![]; // 需要合并的集合 num
            for (index, set) in sets.iter().enumerate() {
                if vv.iter().any(|city| set.contains(city)) {
                    merge.push(index);
                }
            }
            let mut new_set: BTreeSet<String> = vv.into_iter().collect();
            for &index in merge.iter().rev() {
                let oldset = sets.swap_remove(index);
                new_set.extend(oldset);
            }
            sets.push(new_set);
        }
        // dbg!(&sets);
        res.push(sets.len());
    }
    let mut s = String::new();
    for i in res {
        s.push_str(&i.to_string());
        s.push(',');
    }
    // dbg!(&s);
    s.trim_end_matches(',').to_string()
}
